<script setup>
import { ref, watch } from 'vue'
import { Icon, Uploader, showToast, showLoadingToast, Overlay } from 'vant'
import { fileTypeValidator } from '@/utils/validator.js'
import Utility from '@/utils/utility'
const show = ref(false)
const showImage = ref('')
const props = defineProps({
  title: {
    type: String,
    default: '',
  },
  desc: {
    type: String,
    default:
      '支持JPG、JPEG、PNG、PDF、DOC、DOCX、XLS、XLSX等格式，最多上传6个，单个文件限制7M',
  },
  fileTypes: {
    type: Array,
    default: () => ['JPG', 'JPEG', 'PNG', 'PDF', 'DOC', 'DOCX', 'XLS', 'XLSX'],
  },
  maxLength: {
    type: Number,
    default: 6,
  },
  fileSize: {
    type: Number,
    default: 7 * 1024 * 1024,
  },
  isUploadFile: {
    type: String,
    default: '',
  },
  isUploadFileName: {
    type: String,
    default: '',
  },
  delete: {
    type: Boolean,
    default: true,
  },
  hiddenUplod: {
    type: Boolean,
    default: false,
  },
})
const fileNameList = ref([]) // 文件列表
const fileList = ref([]) // 上传后的文件链接
function handleOversize() {
  showToast('文件过大')
}
function beforeRead(file) {
  if (fileList.value.length >= props.maxLength) {
    showToast('文件数量限制')
    return false
  }
  if (!fileTypeValidator(file.name, props.fileTypes)) {
    showToast(`文件限制：${props.fileTypes.join('、')}`)
    return false
  }
  return true
}
async function afterRead(file) {
  let loading = null
  try {
    const formData = new FormData()
    formData.append('files', file.file)
    loading = showLoadingToast({
      duration: 0,
      message: '正在上传...',
      forbidClick: true,
    })
    const { uploadUrl } = await Utility.uploadFileV2(file.file)
    fileNameList.value.push({
      name: file.file.name,
      url: '',
    })
    fileNameList.value[fileNameList.value.length - 1].url = [uploadUrl]
    fileList.value.push(uploadUrl)
  } catch (e) {
    console.log(e)
  } finally {
    loading && loading.close()
  }
}
function cantDelete(index) {
  if (props.delete) return false
  if (!props.isUploadFile) return false
  const len = props.isUploadFile.split(',').length - 1
  return index <= len
}
function deleteFile(index) {
  fileNameList.value.splice(index, 1)
  fileList.value.splice(index, 1)
}

function handlePreview({ url }) {
  let _domain = Utility.getGatewayDomain()
  if (Array.isArray(url)) {
    if (Utility.isNoNeedPreviewFile(url[0])) {
      showToast('不支持预览')
    } else {
      let _url = _domain + '/getFile?fileName=' + url[0]
      showImage.value = [_url]
      show.value = true
    }
  } else {
    if (Utility.isNoNeedPreviewFile(url)) {
      showToast('不支持预览')
    } else {
      let _url = _domain + '/getFile?fileName=' + url
      showImage.value = [_url]
      show.value = true
    }
  }
}
function getFileNameByFileUrl(url) {
  if (!url) return
  let uploadFileNameStr = url.split('/').pop()
  const fileNameStr = uploadFileNameStr.split('_').slice(1).join('_')
  return decodeURIComponent(fileNameStr)
}
function getFileNames(fileUrl) {
  if (!fileUrl) return
  let fileArr = fileUrl.split(',')
  let fileNames = []
  for (const url of fileArr) {
    const name = getFileNameByFileUrl(url)
    fileNames.push(name)
  }
  return fileNames
}
watch(
  () => props.isUploadFile,
  (val) => {
    if (!val) return
    const arr = val.split(',')
    const nameArr = val ? getFileNames(val) : []
    if (arr.length) {
      fileList.value = [...arr]
      fileNameList.value = arr.map((it, index) => {
        return {
          name: nameArr[index] || it,
          url: it,
        }
      })
    }
  },
  {
    immediate: true,
    deep: true,
  }
)
defineExpose({ fileList, fileNameList })
</script>

<template>
  <div class="upload__file">
    <div class="upload__file-tile">
      {{ props.title }}
      <slot name="title" />
    </div>
    <div class="upload__file-desc">{{ props.desc }}</div>
    <div class="file__list">
      <div
        v-for="(item, index) in fileNameList"
        :key="index"
        class="file__item"
      >
        <span class="file__item_name" @click="handlePreview(item)">{{ item.name }}</span>
        <Icon
          v-if="!cantDelete(index)"
          name="cross"
          @click="deleteFile(index)"
        />
      </div>
    </div>
    <Uploader
      v-if="!hiddenUplod"
      accept="image/*, .pdf, .doc, .docx, .xls, .xlsx"
      file-type="text"
      :max-count="props.maxLength"
      :max-size="props.fileSize"
      :after-read="afterRead"
      :before-read="beforeRead"
      @oversize="handleOversize"
    >
      <Icon name="plus" /><span>添加文件</span>
    </Uploader>
    <Overlay :show="show" @click="show = false" z-index="99">
      <div class="img__wrapper wrapper">
        <img :src="showImage" alt="" />
      </div>
    </Overlay>
  </div>
</template>

<style lang="scss" scoped>
.upload__file {
  padding: 15px 0 12px 0;

  .upload__file-tile {
    font-size: 14px;
    color: #222222;
    line-height: 18px;
  }

  .upload__file-desc {
    font-size: 12px;
    color: #999999;
    line-height: 16px;
    margin-top: 4px;
  }

  .file__list {
    margin-top: 10px;

    .file__item {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 8px 12px;
      width: 100%;
      background: #f0f3f6;
      border-radius: 4px;
      font-size: 12px;
      color: #222222;
      margin-bottom: 4px;

      &:last-of-type {
        margin-bottom: 0;
      }
      &_name{
        @include ellipsis(1)
      }
    }
  }

  :deep {
    .van-uploader {
      width: 100%;

      .van-uploader__input-wrapper {
        width: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 14px;
        font-weight: 500;
        color: #3f84f3;
        line-height: 14px;
        margin-top: 10px;

        i {
          font-size: 12px;
          margin-right: 2px;
          font-weight: bold;
        }
      }
    }

    .van-overlay {
      display: flex;
      align-items: center;
      justify-content: center;

      .wrapper img {
        display: block;
        width: 100%;
        height: 100%;
      }
    }
  }
}
</style>
